import re
import os
import sys
from datetime import datetime
import sqlite3

#coding=utf-8

#初始化各种变量
dirpath = 'e:/python/python35/mytest/'

datalist=[]                  #所有提取的数据均存放在该列表中，每一个字典就是一笔交易。

datalist_count=0             #日志文件中的交易总数（包含有效交易、被取消的交易、日志残缺的交易）。

datadict={}                  #每一笔交易记录的各项信息存放在字典中。

Cancel_Trans_count=0         #取消交易计数器。

Cancel_TransID = []          #取消交易的TransID列表。

Trans_effect_count=0         #有效交易计数器。

Trans_full_count =0          #完整交易计数器。

Lack_TransID=[]              #不完整交易记录ID信息。

change_failure_count =0      #找零失败交易计数器。

change_Failure_List  =[]     #找零失败信息列表。

Rechargeable_card_count = 0  #充值交易计数器。

Tvm_Billchgerbiz_List = []   #纸币找零失败信息列表


#定义Get_Tvmbillchger_Errinfo函数

#读取tvmbillchgerBiz.log中的信息,并以列表形式返回故障信息以及发生时间信息

def Get_Tvmbillchger_Errinfo(filename, dirpath):
    if os.path.exists(dirpath + filename):
        try:
            Billchgerbiz_List_Temp = []
            with open(dirpath + filename, 'r', encoding='UTF-8') as f:
                for biztext in f:
                    if '错误码为' in biztext:
                        # 筛选出时间信息
                        tvmbillchgerbiztime_Regex = re.compile(r'\d{2}:\d{2}:\d{2}')
                        tvmbillchgerbiztime = tvmbillchgerbiztime_Regex.findall(biztext)[0]
                        # 筛选出故障信息
                        tvmbillchgerbiztext_Regex = re.compile(r'\[\d+\](.*$)')
                        tvmbillchgerbiztext = tvmbillchgerbiztext_Regex.findall(biztext)
                        Billchgerbiz_List_Temp.append(
                            {'billchgererrtime': tvmbillchgerbiztime, 'billchgererrtext': tvmbillchgerbiztext})
        except IOError:
            print('tvmbillchgerBiz.log读取文件失败或文件不存在。')
        return Billchgerbiz_List_Temp
    else:
        print('tvmbillchgerBiz.log读取文件失败或文件不存在。')

Tvm_Billchgerbiz_List = Get_Tvmbillchger_Errinfo('tvmbillchgerBiz.log',dirpath)
#tvmbillchgerBiz.log文件存时，有匹配内容的时候Tvm_Billchgerbiz_List为正常的列表；
#tvmbillchgerBiz.log文件存时，没有匹配内容的时候Tvm_Billchgerbiz_List为空列表；
#tvmbillchgerBiz.log文件不存时，Tvm_Billchgerbiz_List为None；

#以下作为测试显示使用。

#if len(Tvm_Billchgerbiz_List) > 0:
#    print('该设备纸币找零单元存在故障隐患')
#    print('以下为纸币找零单元发生故障的时间、错误代码以及含义：')
#    #print(Tvm_Billchgerbiz_List)
#
#    for B_B in range(len(Tvm_Billchgerbiz_List)):
#        print('故障时间:' + Tvm_Billchgerbiz_List[B_B]['billchgererrtime'] + ',' '故障描述' + str(Tvm_Billchgerbiz_List[B_B]['billchgererrtext']) )
#    print('#################################以上为纸币模块故障信息###################################\n')



print('#################################以下为TVM主日志关键信息##################################')

'''
Merge_Ticket_Log(dirpath)函数将多个ticket.log日志合并为一个日志文件“mergelogfile.log”，这样数据读取相对较清晰。
'''
def Merge_Ticket_Log(dirpath):
    import glob
    import os
    if os.path.exists(dirpath + 'mergelogfile.log'):
        try:
            os.remove(dirpath + 'mergelogfile.log')
        except IOError:
            print('mergelogfile.log文件删除失败或属性为只读。')
    file_lst = []    #定义文件名排序的列表
    filelist = glob.glob(dirpath + '/tvmticket.*')
    print(filelist)#测试用
    for filename in filelist:
        file_lst.append(filename)
    merge_file = open('mergelogfile.log','w',encoding='UTF-8')
    for ln in file_lst[::-1]:        #file_lst[::-1]能让列表内容倒序排列。
        for log_txt in open(ln,'r',encoding='UTF-8'):
            #ln这个变量还需要进行修改，因为他仅仅是遍历出来的名字，并不带路径。
            merge_file.write(log_txt)
    merge_file.close()

Merge_Ticket_Log(dirpath)    #多个tvmticket.log日志合并为一个日志文件“mergelogfile.log”


'''
 Read_Filter_Ticket(filename, dirpath)函数是读取“mergelogfile.log”文件后筛选出所需要的关键数据并添加到交易列表
'''
def Read_Filter_Ticket(filename,dirpath):
    global datalist,change_failure_count
    try:
        log_file = open(dirpath + filename, 'r', encoding='UTF-8')
    except IOError:
        print('mergelogfile.log文件读取失败或文件不存在。')
    for line in log_file:
        if ('界面消息：[ 售票业务开始 ]消息' in line) or ('界面消息：乘客点击 [ 充值 ]按键.' in line):
            # 利用正则提取售票业务开始时间精确到秒。
            # 该逻辑与之前的代码逻辑有冲突，所以必须对真个程序的逻辑进行调整，时间20170827，当逻辑更改后需要将该信息删除。
            Start_timeRegex = re.compile(r'\d{2}:\d{2}:\d{2}')
            Start_Time = Start_timeRegex.findall(line)[0]
            datalist.append({'StartTime':Start_Time})
            datalist_sub = datalist.index({'StartTime':Start_Time})
        elif '界面消息：乘客点击[张数]' in line:
            if 'datalist_sub' in dir() :
                datalist[datalist_sub].setdefault('BUYMODEL', '乘客最初点击[张数]购票')
        elif '乘客点击票价购票' in line:
            if 'datalist_sub' in dir() :
                datalist[datalist_sub].setdefault('BUYMODEL', '乘客最初点击票价购票')
        elif '目地车站：' in line:
            if 'datalist_sub' in dir() :
                datalist[datalist_sub].setdefault('BUYMODEL', '乘客最初点击车站购票')
        elif '纸币压入结果[ 成功 ]硬币压入结果[ 成功 ]' in line:
            if 'datalist_sub' in dir() :
                datalist[datalist_sub].setdefault('MONEYPRESS', '纸币硬币压入成功')
        elif 'TRANSID' in line:
            # 提取交易id信息，并向列表中添加元素信息（字典）然后读取该元素下标（“datalist_sub”）
            # 提取列表当前元素下标的意义在于方便将其它元素内容添加到该下标的字典中
            if 'datalist_sub' in dir() :
                TRANSID_Regex = re.compile('TRANSID = (\d+)')
                temp_TRANSID = TRANSID_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TRANSID', temp_TRANSID)
        elif 'DeviceCode' in line:
            # 提取设备ID
            if 'datalist_sub' in dir() :
                DeviceCode_Regex = re.compile('DeviceCode = (.*)')
                temp_DeviceCode = DeviceCode_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('DeviceCode', temp_DeviceCode)
        elif 'BizDate' in line:
            if 'datalist_sub' in dir() :
                BizDate_Regex = re.compile('BizDate = (\d{8})')
                temp_BizDate = BizDate_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('BizDate', temp_BizDate)
        elif 'TransDate' in line:
            # 提取购票交易日期
            if 'datalist_sub' in dir() :
                TransDate_Regex = re.compile('TransDate = (\d{8})')
                temp_TransDate = TransDate_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TransDate', temp_TransDate)
        elif 'TransBeginTime' in line:
            # 提取购票交易开始时间
            if 'datalist_sub' in dir() :
                TransBeginTime_Regex = re.compile(r'TransBeginTime = (\d{6})')
                temp_TransBeginTime = TransBeginTime_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TransBeginTime', temp_TransBeginTime)
                # print(datalist)
        elif '乘客点击[ 取消 ]按键. [ 0 ]' in line:
            # 提取乘客是否取消交易操作
            if 'datalist_sub' in dir() :
                datalist[datalist_sub].setdefault('Cancel_Trans', '乘客取消此次操作')
        elif 'Attention: 应付' in line:
            # 提取乘客购票的交易应付款信息
            if 'datalist_sub' in dir() :
                Tinfo_Regex = re.compile('Attention: (.*$)')
                temp_Tinfo = Tinfo_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('Tinfo', temp_Tinfo)
        elif 'write card result: [ 成功 ]' in line:
            # 提取乘客购票的物理卡号信息
            if 'datalist_sub' in dir() :
                #Card_Physics_Id_Regex = re.compile('[0-9a-fA-F]{20}') 最初采用的正则匹配语句感觉有一些不严谨。
                Card_Physics_Id_Regex = re.compile('卡号\[ (.*) \]。')
                temp_Card_Physics_Id = Card_Physics_Id_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('Card_Physics_Id', temp_Card_Physics_Id)
        elif '[TRANS_YPT_INFO]' in line:
            # 提取对一票通交易表的操作信息
            if 'datalist_sub' in dir() :
                TRANS_YPT_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                temp_TRANS_YPT_INFO_Verification = TRANS_YPT_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TRANS_YPT_INFO_Verification',
                                                  temp_TRANS_YPT_INFO_Verification)
        elif '[TRANS_CARD_INFO]' in line:
            # 提取对一卡通交易表信息的操作信息
            if 'datalist_sub' in dir() :
                TRANS_CARD_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                temp_TRANS_CARD_INFO_Verification = TRANS_CARD_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TRANS_CARD_INFO_Verification',
                                                  temp_TRANS_CARD_INFO_Verification)
        elif '[TRANS_CHANGE_INFO]' in line:
            # 提取找零交易信息表的操作信息
            if 'datalist_sub' in dir() :
                TRANS_CHANGE_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                temp_TRANS_CHANGE_INFO_Verification = TRANS_CHANGE_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TRANS_CHANGE_INFO_Verification',
                                                  temp_TRANS_CHANGE_INFO_Verification)
        elif '[TRANS_ENCASH_INFO]' in line:
            # 提取投币交易信息表的操作信息
            if 'datalist_sub' in dir() :
                TRANS_ENCASH_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                temp_TRANS_ENCASH_INFO_Verification = TRANS_ENCASH_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TRANS_ENCASH_INFO_Verification',
                                                  temp_TRANS_ENCASH_INFO_Verification)
        elif 'update [BOX_BILL_DETAIL_INFO]' in line:
            # 提取纸币箱交易明细表的操作信息
            if 'datalist_sub' in dir() :
                BOX_BILL_DETAIL_INFO_Verification_Regex = re.compile(r'szSQL = \[(.*)\]$')
                temp_BOX_BILL_DETAIL_INFO_Verification = BOX_BILL_DETAIL_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('BOX_BILL_DETAIL_INFO_Verification',
                                                  temp_BOX_BILL_DETAIL_INFO_Verification)
        elif '[TRANS_DATA_INFO]' in line:
            # 提取交易明细表的操作信息
            if 'datalist_sub' in dir() :
                TRANS_DATA_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                temp_TRANS_DATA_INFO_Verification = TRANS_DATA_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('TRANS_DATA_INFO_Verification',
                                                  temp_TRANS_DATA_INFO_Verification)
        elif 'find error code' in line:
            # 纸币回收、找零单元故障的故障码以及是“退币失败”还是“找零失败”。
            if 'datalist_sub' in dir() :
                Bill_Error_Regex = re.compile('find error code\[ (.*) \] ')
                Bill_Error_Code_temp = Bill_Error_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('Bill_Error_Code',
                                                  Bill_Error_Code_temp)
                Bill_Error_Info_Regex = re.compile('error name\[ (.*) \]。')
                Bill_Error_Info_temp = Bill_Error_Info_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('Bill_Error_Info',
                                                  Bill_Error_Info_temp)
        elif '应找零：' in line:
            # 筛选应找零金额信息
            if 'datalist_sub' in dir() :
                # print(log_text)
                if 'Should_change' in datalist[datalist_sub].keys():
                    pass
                else:
                    Should_change_Regex = re.compile('应找零： (.*)')
                    temp_Should_change = Should_change_Regex.findall(line)[0]
                    datalist[datalist_sub].setdefault('Should_change', temp_Should_change)
                    # print(datalist[datalist_sub])
        elif '打印一票通故障单 完成' in line:
            # 筛选打印故障单完成信息，来确认故障单是否正常打印成功。
            if 'datalist_sub' in dir() :
                datalist[datalist_sub].setdefault('Fault_list', '打印一票通故障单完成')
                # print(datalist[datalist_sub])
        elif 'Insert into DATA_BIZ_INFO,' in line:
            # 提取DATA_BIZ_INFO表的操作信息
            if 'datalist_sub' in dir() :
                DATA_BIZ_INFO_Verification_Regex = re.compile('values\((.*)\);\]$')
                temp_DATA_BIZ_INFO_Verification = DATA_BIZ_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('DATA_BIZ_INFO_Verification',
                                                  temp_DATA_BIZ_INFO_Verification)
                # print(datalist[datalist_sub])
        elif 'Insert into DATA_BIZ_DEAL_INFO,' in line:
            # 提取DATA_BIZ_DEAL_INFO表的操作信息
            if 'datalist_sub' in dir() :
                DATA_BIZ_DEAL_INFO_Verification_Regex = re.compile('values\((.*)\)\]$')
                temp_DATA_BIZ_DEAL_INFO_Verification = DATA_BIZ_DEAL_INFO_Verification_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('DATA_BIZ_DEAL_INFO_Verification',
                                                  temp_DATA_BIZ_DEAL_INFO_Verification)
                # print(datalist[datalist_sub])
        elif '读取 充值卡 成功。' in line:
            # 提取充值前卡内余额信息
            if 'datalist_sub' in dir() :
                Before_Rechargeablecard_balance_Regex = re.compile('卡片余额\[ (\d+) 分 \]')
                temp_Before_Rechargeablecard_balance = Before_Rechargeablecard_balance_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('Before_Rechargeablecard_balance',
                                                  temp_Before_Rechargeablecard_balance)
        elif '写卡 充值金额为' in line:
            # 提取充值金额相关信息
            if 'datalist_sub' in dir() :
                Rechargeable_card_money_Regex = re.compile('充值金额为 \[ (\d+) \]')
                temp_Rechargeable_card_money = Rechargeable_card_money_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('Rechargeable_card_money',
                                                  temp_Rechargeable_card_money)
                Rechargeable_Put_Money_Regex = re.compile('投入金额\[ (\d+) \]。')
                temp_Rechargeable_Put_Money = Rechargeable_Put_Money_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('Rechargeable_Put_Money',
                                                  temp_Rechargeable_Put_Money)
        elif '界面消息：乘客点击 [ 充值 ]按键.' in line:
            # 提取乘客取消充值交易的操作信息
            if 'datalist_sub' in dir() :
                datalist[datalist_sub].setdefault('Click_Rechargeable', '乘客点击充值按钮')
        elif '充值返回结果URL,返回结果[0]充值后金额' in line:
            # 提取充值后卡内金额信息
            if 'datalist_sub' in dir() :
                After_Rechargeable_card_money_Regex = re.compile('充值后金额\[(\d+)\]')
                temp_After_Rechargeable_card_money = After_Rechargeable_card_money_Regex.findall(line)[0]
                datalist[datalist_sub].setdefault('After_Rechargeable_card_money',
                                                  temp_After_Rechargeable_card_money)
    log_file.close()

Read_Filter_Ticket('mergelogfile.log',dirpath)

print(datalist)
#统计日志文件中的总交易笔数

datalist_count = len(datalist)

'''

定义交易完整数统计函数

'''
def Log_Data_Statistics(datalist):
    global Trans_full_count,Cancel_Trans_count,Cancel_TransID,Lack_TransID,Rechargeable_card_count,change_Failure_List,\
           change_failure_count
    sumcount=len(datalist)
    for x in range(0,sumcount):
        if ((('TRANS_CARD_INFO_Verification' in datalist[x].keys()) or ('TRANS_YPT_INFO_Verification' in datalist[x].keys())) \
                    and ('TRANS_DATA_INFO_Verification' in datalist[x].keys())) \
                and (('TRANS_ENCASH_INFO_Verification' in datalist[x].keys()) \
                             or ('BOX_BILL_DETAIL_INFO_Verification' in datalist[x].keys())):
            Trans_full_count += 1
        # 如果上面的条件都符合那么就说明这个交易是完整的，也许在这个地方是存在疏漏的

        else:
            # 交易日志残缺的交易中包含被取消的交易，所以需要进行一次筛选。

            if 'Cancel_Trans' in datalist[x].keys():
                # 筛选出被取消交易的TRANSID信息

                Cancel_Trans_count += 1  # 被取消交易计数器开始工作

                Cancel_TransID.append(datalist[x].get('TRANSID', 0))  # 将当前TRANSID添加到Cancel_TransID列表中

                #print('以下是被取消交易的TRANSID：' + datalist[x].get('TRANSID', 0))

            else:
                Lack_TransID.append(datalist[x].get('TRANSID', 0))
                #Lack_TransID日志残缺交易的Transid列表

        if '纸币找零失败' in datalist[x].values():
            screen_key = ['TRANSID', 'TransBeginTime', 'Fault_list', 'Tinfo', 'Should_change']
            # 找零失败相关信息在字典中的key，作为元素保存在screen_key列表中。

            screen_key_sum = len(screen_key)
            print(screen_key_sum)
            # 提取screen_key的元素个数。

            for z in range(screen_key_sum):
                # print(datalist[x].get(screen_key[z],0))

                change_Failure_List.append(datalist[x].get(screen_key[z], 0))
                # change_Failure_List作为找零失败相关信息存储的信息列表

                # print(change_Failure_List)

            change_failure_count +=1
        else:
            pass
        if 'Rechargeable_card_money' in datalist[x].keys():
            # 确定交易文件中有多少笔充值交易，以已有充值金额的交易确定该笔交易为充值交易。

            Rechargeable_card_count += 1  # 充值交易计数器开始工作。

        else:
            pass
        
Log_Data_Statistics(datalist)

datalist_count = len(datalist)
#print(change_Failure_List)


Trans_effect_count = datalist_count-Cancel_Trans_count
#有效交易总数（Trans_effect_count）=日志交易总数-被取消交易数


print('日志文件共有中交易记录总数：' + str(datalist_count) + '笔' )
print('有效交易共计：' + str(Trans_effect_count) + '笔（交易总数-被取消交易数）' )
print('充值交易共计：' + str(Rechargeable_card_count) + '笔' )
print('被取消交易共计：'+ str(Cancel_Trans_count) + '笔')
print('被取消交易的TRANSID'+ str(Cancel_TransID))
print('交易日志信息完整的共计：' + str(Trans_full_count) + '笔' )
print('日志残缺的TRANSID:'+ str(Lack_TransID))
print('找零失败的交易共计:'+ str(change_failure_count) + '次')

if change_failure_count > 0 :
    for Failure_List_Show in range(0,len(change_Failure_List),5):
        #Failure_List_Show只作为临时遍历找零失败信息列表的下标。


        print('#####################################################################################\n'
              '****找零失败相关信息:\n'
              '****找零失败TRANSID:' + str(change_Failure_List[Failure_List_Show]) + '\n'
              '****交易时间:' + str(datetime.strptime(change_Failure_List[Failure_List_Show+1], '%H%M%S').time()) + '\n'
              '****故障单:' + str(change_Failure_List[Failure_List_Show+2]) + '\n'
              '****乘客购票信息:' + str(change_Failure_List[Failure_List_Show+3]) + '\n'
              '****故障金额:' + str(change_Failure_List[Failure_List_Show+4]) + '\n'
              '#####################################################################################\n'
              )
#定义一个搜索查询函数


def Tinfo_Search_query(dictlogfile,Search_text):
    Search_text = str(Search_text)
    try:
        dict_log = open(dictlogfile, 'r', encoding='UTF-8')
        #通过双循环遍历出符合查询条件的行。

        for line in dict_log:
            line = eval(line) # 将字符串转换成表达式（日志中读取的逐行信息为）


            for k, v in line.items():
                if Search_text == v:
                    print('#####################################您查询的交易详细信息如下：#####################################')
                    for x,y in line.items():
                        print('{x}:{y}'.format(x=x, y=y))
                    #print(line)

    except Exception as e:
        print('error detail ----。%s。'%e)


'''
Sqlite部分，该部分主要是提取数据库中哪些TRANSID信息缺失，并输出相应的UDSN。
'''
#cx = sqlite3.connect("sledb.db")

#cu = cx.cursor()


conn = sqlite3.connect('test.db')




Tinfo_Search_query('newdict.log',639026)
#Tinfo_Search_query('newdict.log',900869)


#


#Tinfo_Search_query('newdict.log',900539)


#Tinfo_Search_query('newdict.log',900540)


#Tinfo_Search_query('newdict.log',900541)


#Tinfo_Search_query('newdict.log',900542)